using System;
using System.Threading;

namespace AsyncLibrary
{
  /// <summary>Operation from <see cref="VirtualThread"/> point of view</summary>
  public interface IOperation
  {
    /// <summary>Method <see cref="VirtualThread"/> calls to process operation</summary>
    void Run(OperationContext syncContext);
  }

  public class OperationContext
  {
    private readonly SynchronizationContext 
      _syncContext = SynchronizationContext.Current;

    public OperationContext() { }

    public OperationContext(SynchronizationContext context)
    {
      _syncContext = context;
    }

    public bool IsTheSame
    {
      get { return _syncContext == SynchronizationContext.Current; }
    }

    public void Invoke(Action action)
    {
      if (action == null)
        return;
      if (IsTheSame)
      {
        action();
      }
      else
      {
        _syncContext.Post(delegate { action(); }, null);
      }
    }

    public static implicit operator SynchronizationContext(OperationContext c)
    {
      return c._syncContext;
    }
  }
}